// This File is part of the "nyaqt" Project
// 
// Copyright  2009 sometmes@gmail.com
// All rights reserved
// 
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.



using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using nyaqt.Plugins;
using System.Globalization;
using System.Text.RegularExpressions;

namespace nyaqt.DefaultPlugIn
{
    class ConnectionProperties : nyaqt.Plugins.IConnectionProperties
    {
        IDbConnection cn = null;
        public System.Data.IDbConnection Connection
        {
            get
            {
                return this.cn;
            }
            set
            {
                this.cn = value;
            }
        }

        public string Database
        {
            get
            {
                return this.cn.Database; ;
            }
        }

        public string Server
        {
            get
            {
                if (this.cn is DbConnection)
                    return (cn as DbConnection).DataSource;
                else
                    return "";
            }
        }

        public string UserName
        {
            get { return ""; }
        }


        public string ServerBrowseKey
        {
            get { return Server + "/" + UserName; }
        }

        public List<nyaqt.Plugins.DatabaseEntityInfo> GetDatabases()
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.DatabaseName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<nyaqt.Plugins.DatabaseEntityInfo> GetDatabaseTables(string database)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<nyaqt.Plugins.DatabaseEntityInfo> GetDatabaseViews(string database)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<nyaqt.Plugins.DatabaseEntityInfo> GetDatabaseStoredProcedures(string database)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<DatabaseEntityInfo> GetDatabaseSystemTables(string database)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<DatabaseEntityInfo> GetDatabaseTableColumns(string database, string tableNamespace, string table)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<DatabaseEntityInfo> GetDatabaseTableRelations(string database, string tableNamespace, string table)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<DatabaseEntityInfo> GetDatabaseTableRelationColumns(string database, string tableNamespace, string table, string relatedTableNamespace, string relatedTable)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public List<DatabaseEntityInfo> GetDatabaseStoredProcedureParameters(string database, string tableNamespace, string table)
        {
            List<DatabaseEntityInfo> ret = new List<DatabaseEntityInfo>();
            DatabaseEntityInfo e = new DatabaseEntityInfo();
            e.TableName = "The method or operation is not implemented.";
            ret.Add(e);
            return ret;
        }

        public string FormatSelectTopQuery(int top, DatabaseEntityInfo table, List<DatabaseEntityInfo> columns)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public string ConnectionStringPasswordKey
        {
            get { return "Password"; }
        }

        public event ConnectionMessageDelegate ConnectionMessage;

        public string FormatOwnException(int lineoffset, Exception ex)
        {
            return "";
        }

        public string LineCommentString
        {
            get { return "--"; }
        }

        public string SimulateParamsUse(IDbDataParameter[] cmdParams)
        {
            string s = "";
            foreach (IDataParameter param in cmdParams)
            {
                if (s != "")
                    s += ", ";
                s += param.ParameterName + "=" + param.ParameterName;
            }
            if (s != "")
                s = "set " + s;
            string d = "";
            foreach (IDataParameter param in cmdParams)
            {
                if (d != "")
                    d += ", ";
                d += param.ParameterName + " " + FormatDbType(param);
            }
            if (d != "")
                d = "declare " + d;
            string v = "";
            foreach (IDataParameter param in cmdParams)
            {
                if (v != "")
                    v += ", ";
                v += param.ParameterName + "=" + FormatDbValue(param.Value);
            }
            if (v != "")
                v = "set " + v;
            return s + "\r\n-- " + d + "\r\n-- " + v;
        }

        DbType[] strings = new DbType[] { DbType.AnsiString, DbType.AnsiStringFixedLength, DbType.String, DbType.StringFixedLength };
        DbType[] dates = new DbType[] { DbType.Date, DbType.DateTime, DbType.DateTime2, DbType.DateTimeOffset, DbType.Time };
        DbType[] numfixed = new DbType[] { DbType.Currency, DbType.Double, DbType.Single, DbType.Int16, DbType.Int32, DbType.Int64, DbType.UInt16, DbType.UInt32, DbType.UInt64 };
        DbType[] numvar = new DbType[] { DbType.Decimal,DbType.VarNumeric };
        private string FormatDbType(IDataParameter param)
        {
            DbType dbType = param.DbType;
            if (-1 != Array.IndexOf(strings, dbType))
            {
                string s = "" + (param.Value as string);
                return "varchar(" + s.Length + ")";
            }
            if (-1 != Array.IndexOf(dates, dbType))
            {
                return "datetime";
            }
            if (-1 != Array.IndexOf(numfixed, dbType))
            {
                return "int";
            }
            if (-1 != Array.IndexOf(numvar, dbType))
            {
                string d = string.Format(CultureInfo.InvariantCulture, "{F}", param.Value);
                return "numeric(" + (d.Length - 1) + "," + (d.Length - d.IndexOf('.')) + ")";
            }
            else
                return "�" + dbType.ToString() + "?";
        }

        string FormatDbValue(object val)
        {
            if (val is DateTime)
            {
                DateTime dval = (DateTime)val;
                if (dval == dval.Date)
                    return string.Format("'{0:yyyy-MM-dd}'", val);
                else
                    return string.Format("'{0:yyyy-MM-dd hh\\:mm\\:ss\\:fff}'", val);
            }
            else if (val is string)
                return "'" + val + "'";
            else
                return string.Format(CultureInfo.InvariantCulture, "{0}", val);
        }

        public string FormatInsertScript(Dictionary<string, object> nameValueCollection, List<DatabaseEntityInfo> databaseEntityInfo, List<DatabaseEntityInfo> entities)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public string FormatUpdateScript(Dictionary<string, object> rowOriginal, Dictionary<string, object> rowCurrent, List<string> cellsSelected, List<DatabaseEntityInfo> tables, List<DatabaseEntityInfo> columns)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        IConnectionInfo _connectionInfo;
        public IConnectionInfo ConnectionInfo
        {
            get { return _connectionInfo; }
            set { _connectionInfo = value; }
        }


        public string FormatDeleteScript(Dictionary<string, object> rowOriginal, List<DatabaseEntityInfo> tables, List<DatabaseEntityInfo> columns)
        {
            throw new Exception("The method or operation is not implemented.");
        }

        Regex _namedBookmarks = new Regex(@"(?<newline>\n)|PRINT(?<name>[^\r\n]+)\r?\n", RegexOptions.IgnoreCase | RegexOptions.Multiline);
        public List<KeyValuePair<string, int>> ParseNamedBookmarks(string script)
        {
            MatchCollection matches = _namedBookmarks.Matches(script);
            List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
            int line = 0;
            foreach (Match m in matches)
            {
                string newline = m.Groups["newline"].Value;
                string name = m.Groups["name"].Value;
                if (newline != "")
                {
                    line += 1;
                    continue;
                }
                if (name != "")
                {
                    list.Add(new KeyValuePair<string, int>(name.Trim(), line));
                    line += 1;
                    continue;
                }
            }
            return list;
        }

        public void GetConnectionStringKeywordMap(Dictionary<KnownNyaqtConnectionKeys, string> knownKeywords, Dictionary<string, string> keywordMap)
        {
            knownKeywords[KnownNyaqtConnectionKeys.Server] = "Data Source";
            knownKeywords[KnownNyaqtConnectionKeys.Database] = "Initial Catalog";
            knownKeywords[KnownNyaqtConnectionKeys.Login] = "User ID";
            knownKeywords[KnownNyaqtConnectionKeys.Password] = "Password";

            keywordMap["DATA SOURCE"] = knownKeywords[KnownNyaqtConnectionKeys.Server];
            keywordMap["INITIAL CATALOG"] = knownKeywords[KnownNyaqtConnectionKeys.Database];
            keywordMap["USER ID"] = knownKeywords[KnownNyaqtConnectionKeys.Login];
            keywordMap["PASSWORD"] = knownKeywords[KnownNyaqtConnectionKeys.Password];
        }

        public List<ServerInfo> GetServerList()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public bool ServerAddressEqual(string addr1, string addr2)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}
































